package aps.module_Machines;

//Minecraft
import net.minecraft.src.Container;
import net.minecraft.src.EntityPlayer;
import net.minecraft.src.FurnaceRecipes;
import net.minecraft.src.ICrafting;
import net.minecraft.src.IInventory;
import net.minecraft.src.ItemStack;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import net.minecraftforge.common.ForgeDirection;
import net.minecraftforge.common.ISidedInventory;
import aps.module_Core.GuiIDs;
import aps.module_Core.TileEntityAPSPowered;
import aps.module_Core.module_Core.APSBlockTypes;
import buildcraft.BuildCraftCore;
import buildcraft.api.gates.Action;
import buildcraft.api.gates.IAction;
import buildcraft.api.gates.IActionReceptor;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.core.IMachine;
import buildcraft.core.triggers.ActionMachineControl;
//Forge
//Buildcraft
//APS

//100% EFFICIENCY: 200 ENERGY PER ITEM (1600 ENERGY PER COAL IN STEAM ENGINE, 8 ITEMS PER COAL. 1600 / 8 = 200)
//125% EFFICIENCY: 160 ENERGY PER ITEM (1600 ENERGY PER COAL IN STEAM ENGINE, 10 ITEMS PER COAL. 1600 / 10 = 160)

//Stack 0: Ingredients
//Stack 2: Smelted

public class TileEntityPoweredFurnace extends TileEntityAPSPowered implements IPowerReceptor, IInventory, ISidedInventory, IActionReceptor, IMachine
{

    private ItemStack furnaceItemStacks[];
    
    public static int maxStoredPower = 200;
    public int storedPower = 0;
    public int smeltPower = 200;

    public TileEntityPoweredFurnace()
    {
        super( 0, 34, 1, 2, 0, 5, maxStoredPower, 5, maxStoredPower, APSBlockTypes.Machine);
        hasGUI = true;
        GuiID = GuiIDs.GUI_POWERFURNACE;
        furnaceItemStacks = new ItemStack[2];
    }

    public int getSizeInventory()
    {
        return furnaceItemStacks.length;
    }

    public int getStartInventorySide(int side) {
	    if(side==1) return 0;
	    return 1;
    }

    public int getSizeInventorySide(int side) {
	    return 1;
    }

    public ItemStack getStackInSlot(int i)
    {
        return furnaceItemStacks[i];
    }

    public ItemStack decrStackSize(int i, int j)
    {
        if(furnaceItemStacks[i] != null)
        {
            if(furnaceItemStacks[i].stackSize <= j)
            {
                ItemStack itemstack = furnaceItemStacks[i];
                furnaceItemStacks[i] = null;
                return itemstack;
            }
            ItemStack itemstack1 = furnaceItemStacks[i].splitStack(j);
            if(furnaceItemStacks[i].stackSize == 0)
            {
                furnaceItemStacks[i] = null;
            }
            return itemstack1;
        } else
        {
            return null;
        }
    }

    public void setInventorySlotContents(int i, ItemStack itemstack)
    {
        furnaceItemStacks[i] = itemstack;
        if(itemstack != null && itemstack.stackSize > getInventoryStackLimit())
        {
            itemstack.stackSize = getInventoryStackLimit();
        }
    }

    public String getInvName()
    {
        return "Powered Furnace";
    }

    public void readFromNBT(NBTTagCompound nbttagcompound)
    {
        super.readFromNBT(nbttagcompound);
        NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
        furnaceItemStacks = new ItemStack[getSizeInventory()];
        for(int i = 0; i < nbttaglist.tagCount(); i++)
        {
            NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
            byte byte0 = nbttagcompound1.getByte("Slot");
            if(byte0 >= 0 && byte0 < furnaceItemStacks.length)
            {
                furnaceItemStacks[byte0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
            }
        }
    }

    public void writeToNBT(NBTTagCompound nbttagcompound)
    {
        super.writeToNBT(nbttagcompound);
        NBTTagList nbttaglist = new NBTTagList();
        for(int i = 0; i < furnaceItemStacks.length; i++)
        {
            if(furnaceItemStacks[i] != null)
            {
                NBTTagCompound nbttagcompound1 = new NBTTagCompound();
                nbttagcompound1.setByte("Slot", (byte)i);
                furnaceItemStacks[i].writeToNBT(nbttagcompound1);
                nbttaglist.appendTag(nbttagcompound1);
            }
        }

        nbttagcompound.setTag("Items", nbttaglist);
    }

    public int getInventoryStackLimit()
    {
        return 64;
    }

    public int getCookProgressScaled(int i)
    {
    	return (storedPower * i) / smeltPower;
    }

    public int getBurnTimeRemainingScaled(int i)
    {
        return getCookProgressScaled(i);
    }

    public boolean isBurning()
    {
        return getCookProgressScaled(200) > 0;
    }

    public void updateEntity()
    {
        if(lastMode == ActionMachineControl.Mode.On || lastMode == ActionMachineControl.Mode.Loop || lastMode == ActionMachineControl.Mode.Unknown)
        {
        	storedPower += this.powerProvider.useEnergy(5, maxStoredPower, true);
	    	if (storedPower >= smeltPower)
	    	{
	    		storedPower -= smeltPower;
	    		if (storedPower > maxStoredPower)
	    			storedPower = maxStoredPower;
	    		else if (storedPower < 0)
	    			storedPower = 0;
	    		smeltItem();
	    	}
        }
        if(lastMode == ActionMachineControl.Mode.On) lastMode = ActionMachineControl.Mode.Off;
    }

    private boolean canSmelt()
    {
        if(furnaceItemStacks[0] == null)
        {
            return false;
        }
        ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(furnaceItemStacks[0]);
        if(itemstack == null)
        {
            return false;
        }
        if(furnaceItemStacks[1] == null)
        {
            return true;
        }
        if(!furnaceItemStacks[1].isItemEqual(itemstack))
        {
            return false;
        }
        int st = furnaceItemStacks[1].stackSize + itemstack.stackSize;
        return (st <= getInventoryStackLimit() && st <= itemstack.getMaxStackSize());
    }

    public void smeltItem()
    {
        if(!canSmelt())
        {
            return;
        }
        ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(furnaceItemStacks[0]);
        if(furnaceItemStacks[1] == null)
        {
            furnaceItemStacks[1] = itemstack.copy(); //Add smelted stack
        } else
        if(furnaceItemStacks[1].isItemEqual(itemstack))
        {
            furnaceItemStacks[1].stackSize += itemstack.stackSize; //Add to smelted stack
        }
        if(furnaceItemStacks[0].getItem().hasContainerItem())
        {
            furnaceItemStacks[0] = new ItemStack(furnaceItemStacks[0].getItem().getContainerItem());
        } else
        {
            furnaceItemStacks[0].stackSize--; //Decrement ingredient stack
        }
        if(furnaceItemStacks[0].stackSize <= 0)
        {
            furnaceItemStacks[0] = null; //Remove empty stack
        }
    }

    public boolean isUseableByPlayer(EntityPlayer entityplayer)
    {
        if(worldObj.getBlockTileEntity(xCoord, yCoord, zCoord) != this)
        {
            return false;
        }
        return entityplayer.getDistanceSq((double)xCoord + 0.5D, (double)yCoord + 0.5D, (double)zCoord + 0.5D) <= 64D;
    }

    public void openChest()
    {
    }

    public void closeChest()
    {
    }

	public IInventory getInventory() {return this;}
	
	public int powerRequest()
	{
		if (canSmelt())
			return maxStoredPower;
		else
			return 0;
	}

	@Override
	public void kill() {}

	//@Override
	//public GuiScreen getGUI(EntityPlayer entityplayer) {
	//	return new GuiPoweredFurnace(this, entityplayer.inventory);
	//}

	@Override
	public boolean isActive() {return canSmelt();}

	@Override
	public boolean manageLiquids() {return false;}

	@Override
	public boolean manageSolids() {return true;}

	@Override
	public boolean allowActions() {return true;}
	
	ActionMachineControl.Mode lastMode = ActionMachineControl.Mode.Unknown;
	//@Override
	public void actionActivated(Action action) {
		if (action == BuildCraftCore.actionOn) {
			lastMode = ActionMachineControl.Mode.On;
		} else if (action == BuildCraftCore.actionOff) {
			lastMode = ActionMachineControl.Mode.Off;
		} else if (action == BuildCraftCore.actionLoop) {
			lastMode = ActionMachineControl.Mode.Loop;
		}		
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int slot) {
		if (this.furnaceItemStacks[slot] == null)
			return null;
					
		ItemStack stackToReturn = this.furnaceItemStacks[slot];
		this.furnaceItemStacks[slot] = null;
		return stackToReturn;
	}

	@Override
	public void actionActivated(IAction action) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public int getStartInventorySide(ForgeDirection side) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int getSizeInventorySide(ForgeDirection side) {
		// TODO Auto-generated method stub
		return 0;
	}
	
	public void sendGUIUpdates(Container container, ICrafting iCrafting)
	{
		iCrafting.sendProgressBarUpdate(container, 0, this.storedPower);	
	}
	
	public void getGUIUpdates(int channel, int value)
	{
		this.storedPower = value;
	}
}
